package edu.udel.mboch.towerdefense;

import java.io.Serializable;
import java.util.ArrayList;

public abstract class Tower implements Serializable
{
	private static final long serialVersionUID = -8669813460864793676L;
	public static final int BASIC_COST = 100;
	public static final int HEAVY_COST = 175;
	public static final int SLOW_COST = 350;
	public static final int SPLASH_COST = 400;
	
	protected Position position;
	protected ArrayList<Position> positionsInRange;
	protected int damage;
	protected int speed; //Speed is in milliseconds. i.e. a speed of 1000 means 1 shot per 1000 milliseconds (1 shot/sec), 500 means 2 shots/sec.
	protected int range;
	protected int cost;
	protected long timer;
	protected String name;
	
	public Tower(Position position, int range)
	{
		this.position = position;
		this.range = range;
		positionsInRange = positionsInRange();
	}
	
	public Tower(Position position, ArrayList<Position> positionsInRange, int range)
	{
		this.position = position;
		this.range = range;
		timer = 0;
		this.positionsInRange = positionsInRange;
	}
	
	public ArrayList<Position> positionsInRange()
	{
		ArrayList<Position> positions = new ArrayList<Position>();
		for(int i = 0; i<Grid.MAX_Y; i++)
			for(int j = 0; j<Grid.MAX_X; j++)
				if(Math.sqrt(Math.pow(j-position.x(), 2)+Math.pow(i-position.y(),2)) <= range)
					positions.add(new Position(j,i));
		return positions;
	}
	
	public int getDamage()
	{
		return damage;
	}
	
	public int getSpeed()
	{
		return speed;
	}
	
	public int getRange()
	{
		return range;
	}
	
	public String getName()
	{
		return name;
	}
	
	public int getCost()
	{
		return cost;
	}
	
	public Position getPosition()
	{
		return position;
	}
	
	public ArrayList<Position> getPositionsInRange()
	{
		return positionsInRange;
	}
	
	public void addTime(long time)
	{
		timer += time;
	}
	
	public void resetTime()
	{
		timer = 0;
	}
	
	public abstract void shoot(TDState state);
	
	protected ArrayList<Mob> getMobsInRange(TDState state)
	{
		ArrayList<Mob> mobsInRange = new ArrayList<Mob>();
		for(Position p : positionsInRange)
		{
			for(Mob mob : state.getGrid().getMobs())
			{
				if(mob.getPosition().toPosition().equals(p) && state.getPlayer().equals(mob.getPlayer()))
					mobsInRange.add(mob);
				else if(state instanceof BattleTDState && mob.getPosition().toPosition().equals(p) && ((BattleTDState)state).getPlayer2().equals(mob.getPlayer()))
					mobsInRange.add(mob);
					
			}
		}
		return mobsInRange;
	}
	
	public abstract Tower copy();
	
	public abstract void print();
	
	public String toString()
	{
		return position.toString();
	}
}
